package com.ramblingcoder.bc2.server.tool.update;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;

import com.ramblingcoder.bc2.server.tool.update.R;
import com.ramblingcoder.bc2.server.tool.update.commands.SupportingFunctions;
import com.ramblingcoder.bc2.server.tool.update.exceptions.InvalidArguments;
import com.ramblingcoder.bc2.server.tool.update.exceptions.InvalidConfig;
import com.ramblingcoder.bc2.server.tool.update.exceptions.InvalidPassword;
import com.ramblingcoder.bc2.server.tool.update.exceptions.LevelNotLoaded;
import com.ramblingcoder.bc2.server.tool.update.exceptions.LogInRequired;
import com.ramblingcoder.bc2.server.tool.update.exceptions.StartupOnlyCallNotAllowed;
import com.ramblingcoder.bc2.server.tool.update.exceptions.TooLongDescription;
import com.ramblingcoder.bc2.server.tool.update.exceptions.TooLongUrl;
import com.ramblingcoder.bc2.server.tool.update.objects.InfoShare;
import com.ramblingcoder.bc2.server.tool.update.objects.Map;
import com.ramblingcoder.bc2.server.tool.update.objects.Server;

public class SettingsView extends Activity implements OnCheckedChangeListener, OnClickListener {
	//Variables-----\	
	private TextView 
		name,
		version,
		current,
		maximum,
		map, 
		type;
	
	//-----
	
	private CheckBox
		friendlyFire,
		punkbuster,
		ranked,
		teambalance;
	
	//-----
	
	private CheckBox
		spotting,
		vehiclePov,
		crosshair,
		hardcore,
		killcam,
		minimap,
		minimapSpotting,
		profanityFilter;

	private Button 
		timeout;
	//-----
	
	private Button 
		changeBanner,
		changeDescription,
		changeAdminPwd,
		changeGamePwd,
		
		viewBanner;
	//Variables-----/
	
	//Initializer-----\
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
        setContentView(R.layout.settingsview);

        name = (TextView) findViewById(R.id.name);
		version = (TextView) findViewById(R.id.version);
		current = (TextView) findViewById(R.id.current);
		maximum = (TextView) findViewById(R.id.maximum);
		map = (TextView) findViewById(R.id.level);
		type = (TextView) findViewById(R.id.type);
        
        //-----
        
        friendlyFire = (CheckBox) findViewById(R.id.friendlyfire);
        punkbuster = (CheckBox) findViewById(R.id.punkbuster);
        ranked = (CheckBox) findViewById(R.id.ranked);
        teambalance = (CheckBox) findViewById(R.id.teambalance);
        
        //-----
        
        spotting = (CheckBox) findViewById(R.id.spotting);
        vehiclePov = (CheckBox) findViewById(R.id.vehiclepov);
        crosshair = (CheckBox) findViewById(R.id.crosshair);
        hardcore = (CheckBox) findViewById(R.id.hardcore);
        killcam = (CheckBox) findViewById(R.id.killcam);
        minimap = (CheckBox) findViewById(R.id.minimap);
        minimapSpotting = (CheckBox) findViewById(R.id.mapspotting);
        profanityFilter = (CheckBox) findViewById(R.id.profanity);
        timeout = (Button) findViewById(R.id.timeout);
        
        //-----
        
        changeBanner = (Button) findViewById(R.id.changebanner);
        changeDescription = (Button) findViewById(R.id.changedescription);
        changeAdminPwd = (Button) findViewById(R.id.changeadminpwd);
        changeGamePwd = (Button) findViewById(R.id.changegamepwd);
        
        viewBanner = (Button) findViewById(R.id.viewbanner);
        
        try {
			populate();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InvalidArguments e) {
			e.printStackTrace();
		} catch (LogInRequired e) {
			e.printStackTrace();
		} catch (LevelNotLoaded e) {
			e.printStackTrace();
		} catch (InvalidConfig e) {
			e.printStackTrace();
		} catch (StartupOnlyCallNotAllowed e) {
			e.printStackTrace();
		}

        //-------------------------
        
        friendlyFire.setOnCheckedChangeListener(this);
        punkbuster.setOnCheckedChangeListener(this);
        ranked.setOnCheckedChangeListener(this);
        teambalance.setOnCheckedChangeListener(this);
        
        //-----
        
        spotting.setOnCheckedChangeListener(this);
        vehiclePov.setOnCheckedChangeListener(this);
        crosshair.setOnCheckedChangeListener(this);
        hardcore.setOnCheckedChangeListener(this);
        killcam.setOnCheckedChangeListener(this);
        minimap.setOnCheckedChangeListener(this);
        minimapSpotting.setOnCheckedChangeListener(this);
        profanityFilter.setOnCheckedChangeListener(this);
        timeout.setOnClickListener(this);
        
        //-----
        
        changeBanner.setOnClickListener(this);
        changeDescription.setOnClickListener(this);
        changeAdminPwd.setOnClickListener(this);
        changeGamePwd.setOnClickListener(this);
        
        viewBanner.setOnClickListener(this);
        
        friendlyFire.setOnCheckedChangeListener(this);
	}
	
	private void populate() throws IOException, InvalidArguments, LogInRequired, LevelNotLoaded, InvalidConfig, StartupOnlyCallNotAllowed {
		Socket socket = InfoShare.getCommand();
		
		punkbuster.setChecked(Server.punkbusterEnabled(socket, Server.GET));
		friendlyFire.setChecked(Server.friendlyFireEnabled(socket, Server.GET));
		ranked.setChecked(Server.ranked(socket, Server.GET));
		teambalance.setChecked(Server.teamBalance(socket, Server.GET));
		
		spotting.setChecked(Server.spotting3D(socket, Server.GET));
		vehiclePov.setChecked(Server.vehicleCamera(socket, Server.GET));
		crosshair.setChecked(Server.crossHair(socket, Server.GET));
		hardcore.setChecked(Server.hardCore(socket, Server.GET));
		killcam.setChecked(Server.killCam(socket, Server.GET));
		minimap.setChecked(Server.miniMap(socket, Server.GET));
		minimapSpotting.setChecked(Server.miniMapSpotting(socket, Server.GET));
		profanityFilter.setChecked(Server.profanity(socket, Server.GET));
		
		{
			String[] info = Server.getServerInfo(socket);
			
			name.setText(info[0]);
			current.setText(info[1]);
			maximum.setText(info[2]);
			type.setText(Map.findType(info[3]));
			map.setText(Map.findMap(info[4]).getExternalName());
		}
		
		{
			String[] version = Server.getServerVersion(socket);
			this.version.setText(version[0] + " : " + version[1]);
		}
	}

	public boolean onCreateOptionsMenu(Menu menu) {
	    menu.add(1, 5, 0, "Main Menu");
	    menu.add(1, 0, 0, "Refresh");
	    menu.add(1, 1, 0, "Players View");
	    menu.add(1, 2, 0, "Ban View");
	    menu.add(1, 3, 0, "Map View");
	    menu.add(1, 4, 0, "Chat View");
	    menu.add(1, 6, 0, "Reserved View");
	    return true;
	}
	
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	    case 5:
	    	finish();
	    	startActivity(new Intent(this, BC2ServerChoice.class));
	    	break;
	    case 0:
	    	finish();
	    	startActivity(new Intent(this, SettingsView.class));
	    	break;
	    case 1:	
	    	finish();
	    	startActivity(new Intent(this, PlayerView.class));
	    	break;
	    case 2:
	    	finish();
	    	startActivity(new Intent(this, BanView.class));
	    	break;
	    case 3:
	    	finish();
	    	startActivity(new Intent(this, MapView.class));
	    	break;
	    case 4:
	    	finish();
	    	startActivity(new Intent(this, ChatView.class));
	    	break;
	    case 6:
	    	finish();
	    	startActivity(new Intent(this, ReservedView.class));
	    	break;
	    }
	    return true;
	}
	//Initializer-----/

	//Events-----\
	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		Socket socket = InfoShare.getCommand();

		try {
			switch (buttonView.getId()){
				case R.id.punkbuster:
					Server.punkbusterEnabled(socket, (punkbuster.isChecked() ? 1 : 0));
					break;
				case R.id.friendlyfire:
					Server.friendlyFireEnabled(socket, (friendlyFire.isChecked() ? 1 : 0));
					break;
				case R.id.ranked:
					Server.ranked(socket, (ranked.isChecked() ? 1 : 0));
					break;
				case R.id.teambalance:
					Server.teamBalance(socket, (teambalance.isChecked() ? 1 : 0));
					break;
					
				//-----
	
				case R.id.spotting:
					Server.spotting3D(socket, (spotting.isChecked() ? 1 : 0));
					break;
			    case R.id.vehiclepov:
					Server.vehicleCamera(socket, (vehiclePov.isChecked() ? 1 : 0));
					break;
			    case R.id.crosshair:
					Server.crossHair(socket, (crosshair.isChecked() ? 1 : 0));
					break;
			    case R.id.hardcore:
					Server.hardCore(socket, (hardcore.isChecked() ? 1 : 0));
					break;
			    case R.id.killcam:
					Server.killCam(socket, (killcam.isChecked() ? 1 : 0));
					break;
			    case R.id.minimap:
					Server.miniMap(socket, (minimap.isChecked() ? 1 : 0));
					break;
			    case R.id.mapspotting:
					Server.miniMapSpotting(socket, (minimapSpotting.isChecked() ? 1 : 0));
					break;
			    case R.id.profanity:
					Server.profanity(socket, (profanityFilter.isChecked() ? 1 : 0));
					break;
			}
		} catch (IOException e) {
			SupportingFunctions.showError(this, e.getMessage(), new Intent(this, BC2ServerChoice.class));
		} catch (LogInRequired e) {
			SupportingFunctions.showError(this, e.getMessage(), new Intent(this, BC2ServerChoice.class));
		} catch (InvalidArguments e) {
			SupportingFunctions.showError(this, e.getMessage());
		} catch (LevelNotLoaded e) {
			SupportingFunctions.showError(this, e.getMessage(), new Intent(this, SettingsView.class));
		} catch (InvalidConfig e) {
			SupportingFunctions.showError(this, e.getMessage(), new Intent(this, SettingsView.class));
		} catch (StartupOnlyCallNotAllowed e) {
			SupportingFunctions.showError(this, e.getMessage(), new Intent(this, SettingsView.class));
		}
	}

	public void onClick(View v) {
		switch (v.getId()){
		case R.id.changeadminpwd:
			changeAdminPwd();
			break;
		case R.id.changegamepwd:
			changeGamePwd();
			break;
		case R.id.changedescription:
			changeDescription();
			break;
		case R.id.changebanner:
			changeBanner();
			break;
		case R.id.viewbanner:
			try {
				viewBanner();
			} catch (MalformedURLException e) {
				SupportingFunctions.showError(this, e.getMessage());
			} catch (IOException e) {
				SupportingFunctions.showError(this, e.getMessage(), new Intent(this, SettingsView.class));
			} catch (TooLongUrl e) {
				SupportingFunctions.showError(this, e.getMessage());
			} catch (LogInRequired e) {
				SupportingFunctions.showError(this, e.getMessage(), new Intent(this, SettingsView.class));
			} catch (InvalidArguments e) {
				SupportingFunctions.showError(this, e.getMessage());
			}
			break;
		case R.id.timeout:
			changeTimeout();
			break;
		}
	}
	
	private void viewBanner() throws MalformedURLException, IOException, TooLongUrl, LogInRequired, InvalidArguments {
		final Dialog dialog = new Dialog(this);

		dialog.setContentView(R.layout.settings_banner);
		dialog.setTitle("Banner");

		ImageView banner = (ImageView) dialog.findViewById(R.id.bannerimg);
		Button close = (Button) dialog.findViewById(R.id.close);
		
		URL url = new URL(Server.bannerUrl(InfoShare.getCommand(), null));
		HttpURLConnection connection  = (HttpURLConnection) url.openConnection();

		InputStream is = connection.getInputStream();
		Bitmap img = BitmapFactory.decodeStream(is, null, null);   
		
		banner.setImageBitmap(img);
		
		close.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				dialog.dismiss();
			}
		});
		
		dialog.show();
	}

	private void changeTimeout() {
		final Dialog dialog = new Dialog(this);

		dialog.setContentView(R.layout.settings_changegeneral);
		dialog.setTitle("Idle Timeout in Seconds");

		final EditText text = (EditText) dialog.findViewById(R.id.text);
		Button confirm = (Button) dialog.findViewById(R.id.accept);
		Button cancel = (Button) dialog.findViewById(R.id.cancel);
		text.setInputType(InputType.TYPE_CLASS_NUMBER);
		
		try {
			text.setText(Server.idleTimeout(InfoShare.getCommand(), Server.GET) + "");
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (LogInRequired e1) {
			e1.printStackTrace();
		} catch (InvalidArguments e1) {
			e1.printStackTrace();
		}
		
		confirm.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					if (Integer.parseInt(text.getText().toString()) < 0)
						SupportingFunctions.showError(SettingsView.this, "Positive numbers only.");
					else
						Server.idleTimeout(InfoShare.getCommand(), Integer.parseInt(text.getText().toString()));
				} catch (NumberFormatException e) {
					e.printStackTrace();
					SupportingFunctions.showError(SettingsView.this, "Number did not pass validation.");
				} catch (IOException e) {
					e.printStackTrace();
				} catch (LogInRequired e) {
					e.printStackTrace();
				} catch (InvalidArguments e) {
					e.printStackTrace();
				}
				
				dialog.dismiss();
			}
		});
		
		cancel.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				dialog.cancel();
			}
		});
		
		dialog.show();
	}

	private void changeAdminPwd() {
		final Dialog dialog = new Dialog(this);

		dialog.setContentView(R.layout.settings_changegeneral);
		dialog.setTitle("Set Admin Password");

		final EditText text = (EditText) dialog.findViewById(R.id.text);
		Button confirm = (Button) dialog.findViewById(R.id.accept);
		Button cancel = (Button) dialog.findViewById(R.id.cancel);
		
		confirm.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Server.adminPwd(InfoShare.getCommand(), text.getText().toString());
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (InvalidPassword e) {
					e.printStackTrace();
				} catch (LogInRequired e) {
					e.printStackTrace();
				} catch (InvalidArguments e) {
					e.printStackTrace();
				}
				
				dialog.dismiss();
			}
		});
		
		cancel.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				dialog.cancel();
			}
		});
		
		dialog.show();
	}

	private void changeGamePwd() {
		final Dialog dialog = new Dialog(this);

		dialog.setContentView(R.layout.settings_changegeneral);
		dialog.setTitle("Set Game Password");

		final EditText text = (EditText) dialog.findViewById(R.id.text);
		Button confirm = (Button) dialog.findViewById(R.id.accept);
		Button cancel = (Button) dialog.findViewById(R.id.cancel);
		
		confirm.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Server.gamePwd(InfoShare.getCommand(), text.getText().toString());
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (InvalidPassword e) {
					e.printStackTrace();
				} catch (InvalidConfig e) {
					e.printStackTrace();
				} catch (LogInRequired e) {
					e.printStackTrace();
				} catch (InvalidArguments e) {
					e.printStackTrace();
				}
				
				dialog.dismiss();
			}
		});
		
		cancel.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				dialog.cancel();
			}
		});
		
		dialog.show();
	}
	
	private void changeDescription() {
		final Dialog dialog = new Dialog(this);

		dialog.setContentView(R.layout.settings_changegeneral);
		dialog.setTitle("Set Description");

		final EditText text = (EditText) dialog.findViewById(R.id.text);
		text.setWidth(200);
		
		Button confirm = (Button) dialog.findViewById(R.id.accept);
		Button cancel = (Button) dialog.findViewById(R.id.cancel);
		
		try {
			text.setSingleLine(false);
			text.setText(Server.description(InfoShare.getCommand(), null));
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (TooLongDescription e1) {
			e1.printStackTrace();
		} catch (LogInRequired e1) {
			e1.printStackTrace();
		} catch (InvalidArguments e1) {
			e1.printStackTrace();
		}
		
		confirm.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Server.description(InfoShare.getCommand(), text.getText().toString());
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (TooLongDescription e) {
					e.printStackTrace();
				} catch (LogInRequired e) {
					e.printStackTrace();
				} catch (InvalidArguments e) {
					e.printStackTrace();
				}
				
				dialog.dismiss();
			}
		});
		
		cancel.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				dialog.cancel();
			}
		});
		
		dialog.show();
	}
	
	private void changeBanner() {
		final Dialog dialog = new Dialog(this);

		dialog.setContentView(R.layout.settings_changegeneral);
		dialog.setTitle("Set Banner");

		final EditText text = (EditText) dialog.findViewById(R.id.text);
		text.setWidth(200);
		try {
			text.setText(Server.bannerUrl(InfoShare.getCommand(), null));
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (TooLongUrl e) {
			e.printStackTrace();
		} catch (LogInRequired e) {
			e.printStackTrace();
		} catch (InvalidArguments e) {
			e.printStackTrace();
		}
		
		Button confirm = (Button) dialog.findViewById(R.id.accept);
		Button cancel = (Button) dialog.findViewById(R.id.cancel);
		
		confirm.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Server.bannerUrl(InfoShare.getCommand(), text.getText().toString());
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (TooLongUrl e) {
					e.printStackTrace();
				} catch (LogInRequired e) {
					e.printStackTrace();
				} catch (InvalidArguments e) {
					e.printStackTrace();
				}
				
				dialog.dismiss();
			}
		});
		
		cancel.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				dialog.cancel();
			}
		});
		
		dialog.show();
	}
    
    public boolean onKeyDown(int keyCode, KeyEvent event)  {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
        	finish();
        	startActivity(new Intent(this, PlayerView.class));
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }
	//Events-----/
}
